package com.gome.ocean.service.gddl.impl;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gome.framework.util.BeanUtil;
import com.gome.ocean.common.constants.VelocityContants;
import com.gome.ocean.common.enums.DataBaseType;
import com.gome.ocean.common.exception.GddlShardAppVOCreateException;
import com.gome.ocean.common.utils.AddressUtils;
import com.gome.ocean.common.utils.DBSecurityUtil;
import com.gome.ocean.dao.model.datasource.DatasourceBO;
import com.gome.ocean.dao.model.diamond.ConfigInfoBO;
import com.gome.ocean.dao.model.gddl.AppAtomBO;
import com.gome.ocean.dao.model.gddl.GddlShardAppVO;
import com.gome.ocean.dao.model.gddl.GroupDllVO;
import com.gome.ocean.service.datax.DatasourceService;
import com.gome.ocean.service.diamond.ConfigInfoService;
import com.gome.ocean.service.gddl.GddlShardAppService;
import com.gome.ocean.service.task.DataSourceWrapper;
import com.gome.ocean.service.task.LoadDatasourceJobTask;
import com.gome.ocean.service.velocity.VelocityBean;
import com.taobao.tddl.atom.common.TAtomConstants;
import com.taobao.tddl.atom.config.TAtomDsConfDO;
import com.taobao.tddl.atom.securety.impl.PasswordCoder;
import com.taobao.tddl.executor.common.TopologyHandler;
import com.taobao.tddl.group.jdbc.TGroupDataSource;
import com.taobao.tddl.rule.RuleCompatibleHelper;
import com.taobao.tddl.rule.TableRule;
import com.taobao.tddl.rule.TddlRuleConfig;
import com.taobao.tddl.rule.VirtualTableRoot;
import com.taobao.tddl.rule.utils.StringXmlApplicationContext;

@Service
@Transactional
public class GddlShardAppServiceImpl implements GddlShardAppService {

	private static final String ROOT_BEAN_NAME = "vtabroot";
	private static final String DEFAULT_GROUP = "DEFAULT_GROUP";

	@Autowired
	private ConfigInfoService configInfoService;

	@Autowired
	private DatasourceService datasourceService;

	@Autowired
	private VelocityBean velocityBean;
 
	@Override
	@Transactional(value = "diamondTransactionManager", propagation = Propagation.REQUIRED)
	public boolean createGddlShardApp(GddlShardAppVO gddlShardAppVO) {
		List<GddlShardAppVO> gddlShardAppVOs = gddlShardAppVO.getGddlAttrMap();
		String gddlRuleContentNew = velocityBean.assemblePlugins(VelocityContants.GDDL_RULE, gddlShardAppVOs);

		// Map<String, Object> paramMaps = BeanUtil.toMap(gddlShardAppVO);
		// String gddlRuleContent = velocityBean.assemblePlugins(VelocityContants.GDDL_RULE, paramMaps);

		if (StringUtils.isEmpty(gddlRuleContentNew))
			return false;
		VirtualTableRoot virtualTableRoot = buildRuleByStr(gddlRuleContentNew);

		for (int i = 0; i < gddlShardAppVOs.size(); i++) {
			GddlShardAppVO vo = gddlShardAppVOs.get(i);
			TableRule tableRule = virtualTableRoot.getTableRules().get(vo.getLogicTbName().toUpperCase());
			gddlShardAppVOs.get(i).setActualTopology(tableRule.getActualTopology());
		}

		// TableRule tableRule = virtualTableRoot.getTableRules().get(gddlShardAppVO.getLogicTbName().toUpperCase());
		// gddlShardAppVO.setActualTopology(tableRule.getActualTopology());
		// 1,创建GDDL规则
		createGddlRuleInfo(gddlShardAppVOs, gddlRuleContentNew, gddlShardAppVO.getVersion());
		// 2,创建分组信息
		createGddlDbGroupsInfo(gddlShardAppVOs, virtualTableRoot.getTableRules());
		// 3,创建单组信息
		createGddlGroupInfo(gddlShardAppVO, virtualTableRoot.getTableRules());
		// 4,创建atom信息
		createAtomGlobalInfo(gddlShardAppVOs, virtualTableRoot.getTableRules());
		return true;
	}

	@Override
	public boolean checkGddlShardApp(GddlShardAppVO gddlShardAppVO) {
		@SuppressWarnings("unchecked")
		Map<String, Object> paramMaps = BeanUtil.toMap(gddlShardAppVO);
		String gddlRuleContent = velocityBean.assemblePlugins(VelocityContants.GDDL_RULE, paramMaps);

		if (StringUtils.isEmpty(gddlRuleContent))
			return false;
		VirtualTableRoot virtualTableRoot = buildRuleByStr(gddlRuleContent);
		TableRule tableRule = virtualTableRoot.getTableRules().get(gddlShardAppVO.getLogicTbName().toUpperCase());

		// 1,检查GDDL规则
		String versionDataId = TddlRuleConfig.getVersionsDataId(gddlShardAppVO.getLogicTbName());
		ConfigInfoBO configInfoBO = configInfoService.findConfigInfoBOByDataId(versionDataId);
		if (configInfoBO == null)
			return false;

		String ruleDataId = TddlRuleConfig.getVersionedRuleDataId(gddlShardAppVO.getLogicTbName(), gddlShardAppVO.getVersion());
		configInfoBO = configInfoService.findConfigInfoBOByDataId(ruleDataId);
		if (configInfoBO == null)
			return false;

		// 2,检查分组信息
		String dbgroupsDataId = TopologyHandler.GROUP_TOPOLOGY.format(new Object[] { gddlShardAppVO.getLogicTbName() });
		configInfoBO = configInfoService.findConfigInfoBOByDataId(dbgroupsDataId);
		if (configInfoBO == null)
			return false;

		int datasourceId = 0;
		// 3,检查单组信息
		for (Entry<String, Set<String>> dbgroup : tableRule.getActualTopology().entrySet()) {
			String groupDataId = TGroupDataSource.getFullDbGroupKey(dbgroup.getKey());
			configInfoBO = configInfoService.findConfigInfoBOByDataId(groupDataId);
			if (configInfoBO == null)
				return false;

			DatasourceBO datasourceBO = datasourceService.findDatasourceBOById(gddlShardAppVO.getShardDbs().get(datasourceId));

			String name = StringUtils.remove(dbgroup.getKey(), "group_");
			String atomDataId = TAtomConstants.getAppDataId(gddlShardAppVO.getLogicTbName(), name);
			configInfoBO = configInfoService.findConfigInfoBOByDataId(atomDataId);
			if (configInfoBO == null)
				return false;

			String dbName = StringUtils.substringAfterLast(datasourceBO.getJdbcUrl(), "/");

			String globalDataId = TAtomConstants.getGlobalDataId(name);
			configInfoBO = configInfoService.findConfigInfoBOByDataId(globalDataId);
			if (configInfoBO == null)
				return false;

			String passwdDataId = TAtomConstants.getPasswdDataId(dbName, DataBaseType.getDataBaseType(datasourceBO.getSourceType()).getTypeFullName(), datasourceBO.getUserName());
			configInfoBO = configInfoService.findConfigInfoBOByDataId(passwdDataId);
			if (configInfoBO == null)
				return false;
		}
		return true;
	}

	/**
	 * atom:com.taobao.tddl.atom.app.{0}.{1}
	 * global:com.taobao.tddl.atom.global.{0}
	 *
	 * @param gddlShardAppVO
	 * @param tableRule
	 */
	private void createAtomGlobalInfo(GddlShardAppVO gddlShardAppVO, TableRule tableRule) {
		int datasourceId = 0;
		for (Entry<String, Set<String>> dbgroup : gddlShardAppVO.getActualTopology().entrySet()) {

			DatasourceBO datasourceBO = datasourceService.findDatasourceBOById(gddlShardAppVO.getShardDbs().get(datasourceId));

			String name = StringUtils.remove(dbgroup.getKey(), "group_");
			String atomDataId = TAtomConstants.getAppDataId(gddlShardAppVO.getAppName(), name);
			String atomContent = getAtomContent(datasourceBO.getUserName());
			insertDiamond(atomDataId, atomContent);

			DataSourceTmp dataSourceTmp = parseDataSourceTmp(datasourceBO);
			String globalDataId = TAtomConstants.getGlobalDataId(name);
			String globalContent = getBlobalContent(dataSourceTmp.getIp(), dataSourceTmp.getPort(), dataSourceTmp.getDbname());
			insertDiamond(globalDataId, globalContent);

			String passwdDataId = TAtomConstants.getPasswdDataId(dataSourceTmp.getDbname(), DataBaseType.getDataBaseType(datasourceBO.getSourceType()).getTypeFullName(), datasourceBO.getUserName());
			String passwdContent = null;
			try {
				passwdContent = "encPasswd=".concat(new PasswordCoder().encode(dataSourceTmp.getPassword()));
			} catch (InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException e) {
				e.printStackTrace();
			}
			insertDiamond(passwdDataId, passwdContent);

			// 创建备库
			if (gddlShardAppVO.isBack()) {
				datasourceBO = datasourceService.findDatasourceBOById(gddlShardAppVO.getBackDbs().get(datasourceId));
				atomContent = getAtomContent(datasourceBO.getUserName());
				insertDiamond(atomDataId.concat("_bak"), atomContent);

				DataSourceTmp backDataSourceTmp = parseDataSourceTmp(datasourceBO);
				globalContent = getBlobalContent(backDataSourceTmp.getIp(), backDataSourceTmp.getPort(), backDataSourceTmp.getDbname());
				insertDiamond(globalDataId.concat("_bak"), globalContent);

				if (!dataSourceTmp.getDbname().equals(backDataSourceTmp.getDbname())
						&& DataBaseType.getDataBaseType(datasourceBO.getSourceType()) != DataBaseType.getDataBaseType(dataSourceTmp.getSourcetype())
						&& !dataSourceTmp.getUsername().equals(backDataSourceTmp.getUsername())) {

					passwdDataId = TAtomConstants.getPasswdDataId(backDataSourceTmp.getDbname(), DataBaseType.getDataBaseType(backDataSourceTmp.getSourcetype()).getTypeFullName(),
							datasourceBO.getUserName());
					passwdContent = null;
					try {
						passwdContent = "encPasswd=".concat(new PasswordCoder().encode(backDataSourceTmp.getPassword()));
					} catch (InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException e) {
						e.printStackTrace();
					}
					insertDiamond(passwdDataId, passwdContent);
				}
			}

			// 是否创建数据结构
			if (gddlShardAppVO.isCreateTable()) {
				createGddlTable(gddlShardAppVO, datasourceBO, dbgroup.getValue());
			}
			datasourceId++;
		}
	}

	private void createAtomGlobalInfo(List<GddlShardAppVO> gddlShardAppVOs, Map<String, TableRule> tableRules) {
		for (GddlShardAppVO gddlShardAppVO : gddlShardAppVOs) {
			TableRule tableRule = tableRules.get(gddlShardAppVO.getLogicTbName().toUpperCase());
			createAtomGlobalInfo(gddlShardAppVO, tableRule);
		}
	}

	/**
	 * 分解IP PORT DBNAME
	 * 
	 * @param datasourceBO
	 * @return
	 */
	private DataSourceTmp parseDataSourceTmp(DatasourceBO datasourceBO) {
		DataSourceTmp dataSourceTmp = new DataSourceTmp();
		String[] ipPorts = null;
		// IP地址解析
		String ipPort = AddressUtils.getIpPort(datasourceBO.getJdbcUrl());
		if (StringUtils.isNotEmpty(ipPort)) {
			ipPorts = ipPort.split(":");
		} else {
			// 域名解析
			ipPorts = StringUtils.substringBetween(datasourceBO.getJdbcUrl(), "//", "/").split(":");
		}
		String dbName;
		if (datasourceBO.getJdbcUrl().indexOf("?") > 0) {
			dbName = StringUtils.substringBefore(StringUtils.substringAfterLast(datasourceBO.getJdbcUrl(), "/"), "?");
		} else {
			dbName = StringUtils.substringAfterLast(datasourceBO.getJdbcUrl(), "/");
		}
		dataSourceTmp.setIp(ipPorts[0]);
		dataSourceTmp.setPort(ipPorts[1]);
		dataSourceTmp.setDbname(dbName);
		dataSourceTmp.setUsername(datasourceBO.getUserName());
		dataSourceTmp.setSourcetype(datasourceBO.getSourceType());
		dataSourceTmp.setPassword(datasourceBO.getPassword());
		return dataSourceTmp;
	}

	class DataSourceTmp {

		private String ip;
		private String port;
		private String dbname;
		private String username;
		private String sourcetype;
		private String password;

		public String getIp() {
			return ip;
		}

		public void setIp(String ip) {
			this.ip = ip;
		}

		public String getPort() {
			return port;
		}

		public void setPort(String port) {
			this.port = port;
		}

		public String getDbname() {
			return dbname;
		}

		public void setDbname(String dbname) {
			this.dbname = dbname;
		}

		public String getUsername() {
			return username;
		}

		public void setUsername(String username) {
			this.username = username;
		}

		public String getSourcetype() {
			return sourcetype;
		}

		public void setSourcetype(String sourcetype) {
			this.sourcetype = sourcetype;
		}

		public String getPassword() {
			return password;
		}

		public void setPassword(String password) {
			this.password = password;
		}
	}

	/**
	 * 创建分表数据
	 *
	 * @param datasourceBO
	 * @param tables
	 * @throws GddlShardAppVOCreateException
	 */
	private void createGddlTable(GddlShardAppVO gddlShardAppVO, DatasourceBO datasourceBO, Set<String> tables) {
		DataSourceWrapper dataSourceWrapper = createDruidDataSource(datasourceBO);
		MessageFormat messageFormat = new MessageFormat(gddlShardAppVO.getShardSql());
		for (String tableName : tables) {
			dataSourceWrapper.update(messageFormat.format(new Object[] { tableName }));
		}
		dataSourceWrapper.close();
	}

	/**
	 * 创建druid数据源
	 *
	 * @param appDatasourceBO
	 * @return
	 */
	private DataSourceWrapper createDruidDataSource(DatasourceBO datasourceBO) {
		DruidDataSource localDruidDataSource = new DruidDataSource();
		localDruidDataSource.setTestOnBorrow(false);
		localDruidDataSource.setTestWhileIdle(true);
		localDruidDataSource.setUsername(datasourceBO.getUserName());
		localDruidDataSource.setPassword(datasourceBO.getPassword());
		if (datasourceBO.getSourceType().equals("oracle")) {
			localDruidDataSource.setDriverClassName(DataBaseType.Oracle.getDriverClassName());
			localDruidDataSource.setUrl(datasourceBO.getJdbcUrl());
			localDruidDataSource.setDbType(DataBaseType.Oracle.getTypeFullName());
			// localDruidDataSource.setValidationQuery(TAtomConstants.DEFAULT_DRUID_ORACLE_VALIDATION_QUERY);
		} else {
			localDruidDataSource.setDriverClassName(DataBaseType.MySql.getDriverClassName());
			localDruidDataSource.setUrl(datasourceBO.getJdbcUrl());
			localDruidDataSource.setDbType(DataBaseType.MySql.getTypeFullName());
			// localDruidDataSource.setValidationQuery(TAtomConstants.DEFAULT_DRUID_MYSQL_VALIDATION_QUERY);
		}
		// lazy init 先设置为0 后续真正执行时才创建连接
		localDruidDataSource.setInitialSize(TAtomDsConfDO.defaultInitPoolSize);
		localDruidDataSource.setMinIdle(LoadDatasourceJobTask.DEFAULT_POOL_SIZE);
		localDruidDataSource.setMaxActive(LoadDatasourceJobTask.DEFAULT_POOL_SIZE);
		// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		localDruidDataSource.setTimeBetweenEvictionRunsMillis(15 * 60 * 1000);
		// 配置一个连接在池中最小生存的时间，单位是毫秒
		localDruidDataSource.setMinEvictableIdleTimeMillis(15 * 60 * 1000);
		localDruidDataSource.setMaxWait(TAtomDsConfDO.defaultMaxWait);
		return new DataSourceWrapper(localDruidDataSource);
	}

	private String getBlobalContent(String ip, String port, String dbName) {
		StringBuffer globalContent = new StringBuffer();
		globalContent.append("ip={0}\r").append("port={1}\r").append("dbName={2}\r").append("dbType=mysql\r").append("dbStatus=RW\r");
		return new MessageFormat(globalContent.toString()).format(new Object[] { ip, port, dbName });
	}

	private String getAtomContent(String userName) {
		StringBuffer atomContent = new StringBuffer();
		atomContent.append("userName={0}\r").append("minPoolSize=5\r").append("maxPoolSize=10\r").append("idleTimeout=10\r").append("blockingTimeout=5000\r").append("preparedStatementCacheSize=15\r")
				.append("connectionProperties=characterEncoding=utf-8\r");
		return new MessageFormat(atomContent.toString()).format(new Object[] { userName });
	}

	/**
	 * 创建GDDL rule
	 *
	 * @param gddlShardAppVO
	 * @param gddlRule
	 */
	private void createGddlRuleInfo(GddlShardAppVO gddlShardAppVO, String gddlRuleContent) {
		String versionDataId = TddlRuleConfig.getVersionsDataId(gddlShardAppVO.getAppName());
		String versionContent = gddlShardAppVO.getVersion();
		insertDiamond(versionDataId, versionContent);

		String ruleDataId = TddlRuleConfig.getVersionedRuleDataId(gddlShardAppVO.getAppName(), versionContent);
		insertDiamond(ruleDataId, gddlRuleContent);
	}

	private void createGddlRuleInfo(List<GddlShardAppVO> gddlShardAppVOs, String gddlRuleContent, String versionContent) {
		for (GddlShardAppVO gddlShardAppVO : gddlShardAppVOs) {
			String versionDataId = TddlRuleConfig.getVersionsDataId(gddlShardAppVO.getAppName());
			insertDiamond(versionDataId, versionContent);

			String ruleDataId = TddlRuleConfig.getVersionedRuleDataId(gddlShardAppVO.getAppName(), versionContent);
			insertDiamond(ruleDataId, gddlRuleContent);
		}
	}

	/**
	 * 创建GDDL group
	 *
	 * @param gddlShardAppVO
	 * @param gddlRule
	 */
	private void createGddlGroupInfo(GddlShardAppVO gddlShardAppVO, TableRule tableRule) {
		for (Entry<String, Set<String>> dbgroup : tableRule.getActualTopology().entrySet()) {
			String groupDataId = TGroupDataSource.getFullDbGroupKey(dbgroup.getKey());
			StringBuffer groupContent = new StringBuffer();
			String sourceName = StringUtils.remove(dbgroup.getKey(), "group_");
			groupContent.append(sourceName).append(":").append("r10w10");
			if (gddlShardAppVO.isBack()) {
				groupContent.append(",").append(sourceName).append("_bak:b");
			}
			insertDiamond(groupDataId, groupContent.toString());
		}
	}

	private void createGddlGroupInfo(GddlShardAppVO gddlShardAppVO, Map<String, TableRule> tableRules) {
		
		for (String key : tableRules.keySet()) {
			TableRule tableRule = tableRules.get(key);
			for (Entry<String, Set<String>> dbgroup : tableRule.getActualTopology().entrySet()) {
				String groupDataId = TGroupDataSource.getFullDbGroupKey(dbgroup.getKey());
				StringBuffer groupContent = new StringBuffer();
				String sourceName = StringUtils.remove(dbgroup.getKey(), "group_");
				groupContent.append(sourceName).append(":").append("r10w10");
				
					if (gddlShardAppVO.isBack()) {
						groupContent.append(",").append(sourceName).append("_bak:b");
					}
					insertDiamond(groupDataId, groupContent.toString());
				}
			}

	}

	/**
	 * 创建GDDL db groups
	 */
	private void createGddlDbGroupsInfo(GddlShardAppVO gddlShardAppVO, TableRule tableRule) {
		String dbgroupsDataId = TopologyHandler.GROUP_TOPOLOGY.format(new Object[] { gddlShardAppVO.getAppName() });
		String dbgroupscontent = StringUtils.join(tableRule.getActualTopology().keySet(), ",");
		insertDiamond(dbgroupsDataId, dbgroupscontent);
	}

	private void createGddlDbGroupsInfo(List<GddlShardAppVO> gddlShardAppVOs, Map<String, TableRule> tableRules) {

		for (GddlShardAppVO gddlShardAppVO : gddlShardAppVOs) {
			String dbgroupsDataId = TopologyHandler.GROUP_TOPOLOGY.format(new Object[] { gddlShardAppVO.getAppName() });
			TableRule tableRule = tableRules.get(gddlShardAppVO.getLogicTbName().toUpperCase());
			String dbgroupscontent = StringUtils.join(tableRule.getActualTopology().keySet(), ",");
			insertDiamond(dbgroupsDataId, dbgroupscontent);
		}
	}

	/**
	 * 插入到diamond
	 *
	 * @param dataId
	 * @param context
	 */
	private void insertDiamond(String dataId, String content) {
		ConfigInfoBO configInfoBO = configInfoService.findConfigInfoBOByDataId(dataId);
		if (configInfoBO == null)
			configInfoBO = new ConfigInfoBO();
		configInfoBO.setDataId(dataId);
		configInfoBO.setContent(content);
		configInfoBO.setGroupId(DEFAULT_GROUP);
		configInfoService.saveConfigInfoBO(configInfoBO);
	}

	/**
	 * 编译 TDDL rule配置
	 *
	 * @param version
	 * @param data
	 * @return
	 */
	private VirtualTableRoot buildRuleByStr(String data) {
		data = RuleCompatibleHelper.compatibleRule(data);
		@SuppressWarnings("resource")
		ApplicationContext applicationContext = new StringXmlApplicationContext(data, this.getClass().getClassLoader());
		VirtualTableRoot tempvtr = (VirtualTableRoot) applicationContext.getBean(ROOT_BEAN_NAME);
		return tempvtr;
	}

	@Override
	public boolean createGddlGroupApp(GroupDllVO groupDllVO) {
		createGddlDBGroupV1(groupDllVO);
		createGddlDBGroup(groupDllVO);
		return true;
	}

	// 分组不需要，弃用
	// 生成v1信息并通知diamond
	private void createGddlDBGroupV1(GroupDllVO groupDllVO) {
		String dataId = TopologyHandler.GROUP_TOPOLOGY.format(new Object[] {groupDllVO.getAppName()});
		String content = groupDllVO.getGroupName();
		insertDiamond(dataId, content);
	}

	// 生成读写分离信息并通知diamond
	private void createGddlDBGroup(GroupDllVO groupDllVO) {
		String dataId = TGroupDataSource.getFullDbGroupKey(groupDllVO.getGroupName());
		StringBuffer sbContent = new StringBuffer();
		JSONArray datalistArray = JSONArray.parseArray(groupDllVO.getDatabaseList());
		JSONArray backupDatalistArray=new JSONArray();
		
		
		for (Object object : datalistArray) {
			JSONObject tempJson = JSONObject.parseObject(object.toString());
			sbContent.append(tempJson.getString("dbName")).append(":").append("r").append(tempJson.getString("readWeight")).append("w").append(tempJson.getString("writeWeight")).append(",");
			createGddlDBGroupDbinfo(object.toString(),groupDllVO.getAppName());
		}
		
		if(!("false".equals(groupDllVO.getBackupDataList()))){
			backupDatalistArray=JSONArray.parseArray(groupDllVO.getBackupDataList());
			for (Object object : backupDatalistArray) {
				JSONObject tempBackJson = JSONObject.parseObject(object.toString());
				sbContent.append(tempBackJson.getString("dbName")).append(":").append("b").append(",");
				createGddlDBGroupDbinfo(object.toString(),groupDllVO.getAppName());
			}
		}
		String content=sbContent.toString().substring(0,(sbContent.toString().lastIndexOf(",")));
		insertDiamond(dataId,content);
		
		
		
	}
	
	private void createGddlDBGroupDbinfo(String databaseInfo,String appName){
		JSONObject databaseJson=JSONObject.parseObject(databaseInfo);
		DatasourceBO datasourceBO=datasourceService.findDatasourceBOById(databaseJson.getLong("datasourceId"));
		DataSourceTmp dataSourceTmp = parseDataSourceTmp(datasourceBO);
		String globalDataId=TAtomConstants.getGlobalDataId(databaseJson.getString("dbName"));
		StringBuffer sbGlobalContent=new StringBuffer();
		sbGlobalContent.append("ip=").append(databaseJson.getString("datasourceIp")).append("\r");
		sbGlobalContent.append("port=").append(databaseJson.getString("datasourcePort")).append("\r");
		sbGlobalContent.append("dbName=").append(dataSourceTmp.getDbname()).append("\r");
		sbGlobalContent.append("dbType=").append("3".equals(datasourceBO.getSourceType())?"oracle":"mysql").append("\r");
		sbGlobalContent.append("dbStatus=").append("RW");
		
		String globalContent=sbGlobalContent.toString();
		insertDiamond(globalDataId,globalContent);
		 
		String pwdDataId=TAtomConstants.getPasswdDataId(dataSourceTmp.getDbname(), ("3".equals(datasourceBO.getSourceType())?"oracle":"mysql"), datasourceBO.getUserName());
		StringBuffer passwdContent = new StringBuffer();
		try {
			passwdContent.append("encPasswd=").append(new PasswordCoder().encode(datasourceBO.getPassword()));
		}catch (InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException e) {
			e.printStackTrace();
		} 
		insertDiamond(pwdDataId, passwdContent.toString());
		
		
		String atomAppDataId=TAtomConstants.getAppDataId(appName, databaseJson.getString("dbName"));
		String atomAppContent=getAtomContent(datasourceBO.getUserName());
		insertDiamond(atomAppDataId, atomAppContent);
		
	}
	
	@Override
	public void updateDiamond(String dataId, String content){
		insertDiamond(dataId,content);
	}

	@Override
	public boolean createAppAtom(AppAtomBO appAtomBO) {
		//createAtomGlobal
		createAtomGlobal(appAtomBO.getDataSourceInfo(),appAtomBO.getDbkey());
		createAtomPwd(appAtomBO.getDataSourceInfo(),appAtomBO.getEnckey());
		createAtomApp(appAtomBO.getAppName(), appAtomBO.getAppDataSourceInfo(), appAtomBO.getDataSourceInfo(), appAtomBO.getDbkey());	
		return true;
	}
	
	private boolean createAtomGlobal(String dataSourceInfo ,String dbKey) {
		StringBuffer sbContent=new StringBuffer();
		JSONObject datasourceJson=JSONObject.parseObject(dataSourceInfo);
		sbContent.append("ip=").append(datasourceJson.getString("databaseIp")).append("\r");
		sbContent.append("port=").append(datasourceJson.getString("databasePort")).append("\r");
		sbContent.append("dbName=").append(datasourceJson.getString("databaseName")).append("\r");
		sbContent.append("dbType=").append(datasourceJson.getString("databaseType")).append("\r");
		sbContent.append("dbStatus=").append("RW");
		String dataId=TAtomConstants.getGlobalDataId(dbKey);
		insertDiamond(dataId, sbContent.toString());
		return true;
	}
	
	private boolean createAtomPwd(String dataSourceInfo,String enckey) {
		JSONObject datasourceJson=JSONObject.parseObject(dataSourceInfo);
		Long dataSourceId=datasourceJson.getLong("databaseId");
		DatasourceBO datasourceBO=datasourceService.findDatasourceBOById(dataSourceId);
		StringBuffer passwdContent = new StringBuffer();
		
		try {
			if(StringUtils.isBlank(enckey)){
				passwdContent.append("encPasswd=").append(new PasswordCoder().encode(datasourceBO.getPassword()));
			}else{
				passwdContent.append("encPasswd=").append(new PasswordCoder().encode(enckey, datasourceBO.getPassword())).append("\r");
				passwdContent.append("encKey=").append(enckey);
			}
			
		} catch (InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException e) {
			e.printStackTrace();
		}
		String passwdDataId = TAtomConstants.getPasswdDataId(datasourceJson.getString("databaseName"), datasourceJson.getString("databaseType"), datasourceBO.getUserName());
		insertDiamond(passwdDataId, passwdContent.toString());
		return true;
	}
	
	private boolean createAtomApp(String appName,String appDataSourceInfo,String dataSourceInfo,String dbkey){
		String appDataId=TAtomConstants.getAppDataId(appName, dbkey);
		JSONObject datasourceJson=JSONObject.parseObject(dataSourceInfo);
		Long dataSourceId=datasourceJson.getLong("databaseId");
		DatasourceBO datasourceBO=datasourceService.findDatasourceBOById(dataSourceId);
		StringBuffer appDataContent=new StringBuffer();
		appDataContent.append("userName=").append(datasourceBO.getUserName()).append("\r").append(appDataSourceInfo);
		insertDiamond(appDataId, appDataContent.toString());
		return true;
	}
	
	public static void main(String[] args) {
	       try {
	           //7EtovHdo8iAncnLxjaKAA
	           
	           //Kms7Z1YJGS4y4WS7
	        //String abc =  new PasswordCoder().encode("8EEDGPUC9lsY5kTl");
	       String abc = new PasswordCoder().decode("Z2hhdAFHbO41cDjh", "527aadfcc97d77064d78e334f7a82b26e3b8f24e67941daeacf11cfc42f7aaa4");
	       String ddd = DBSecurityUtil.decrypt("527aadfcc97d77064d78e334f7a82b26e3b8f24e67941daeacf11cfc42f7aaa4", "HpZ2hhdAFHbO41cDjhkWV");
	        System.out.println(abc);
	        System.out.println(ddd);
	    } catch (InvalidKeyException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    } catch (NoSuchPaddingException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    } catch (NoSuchAlgorithmException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    } catch (BadPaddingException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    } catch (IllegalBlockSizeException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    }
	    }
	
}
